/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.core.manager;

import com.brain.core.common.UtilCore;
import com.brain.core.configuracion.WebServletContextListener;
import com.brain.core.dto.EmpresaDto;
import com.brain.core.dto.FeriadoOrganizacionDto;
import com.brain.core.dto.FeriadoPaisDto;

import com.brain.core.exception.DAOException;
import com.brain.core.hibernate.dao.DAOGenerico;
import com.brain.core.view.mbean.ApplicationMBean;
import com.brain.core.view.mbean.SessionMBean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 *
 * @author Indra
 */
@Service
public class FeriadoPaisManager extends ComunManager<FeriadoPaisDto> implements Serializable {

    private static Logger logger = Logger.getLogger(FeriadoPaisManager.class);
    private Long idEntidad = 154L;
    @Resource
    private DAOGenerico<FeriadoPaisDto> springHibernateDao;
    @Resource
    private RecursosManager recursosManager;
    private final String url = "/pages/core/feriadoPais/listaFeriados.xhtml";
    private Long idEmpresaSystem = 0L;
    private EmpresaDto empresaSystem;

    /**
     * Metodo para obtener un feriado por su ID
     *
     * @param id ID del feriado
     * @return Feriado
     * @throws DAOException
     */
    public FeriadoPaisDto obtenerPorId(Long id) throws DAOException {
        return springHibernateDao.obtenerDtoPorId(FeriadoPaisDto.class, id);
    }

    /**
     * Metodo para obtener feriados de acuerdo a un filtro
     *
     * @param dtoFiltro filtros
     * @return lista de feriados
     * @throws DAOException
     */
    public List<FeriadoPaisDto> obtenerFeriadosPorPaisYAnio(FeriadoPaisDto dtoFiltro) throws DAOException {
        List<Object> listaParametros = new ArrayList<Object>();
        String hqsql = "select e from FeriadoPaisDto as e where e.id=e.id";
        if (dtoFiltro.getId() != null && !dtoFiltro.getId().equals(0L)) {
            hqsql += " and e.id = ?";
            listaParametros.add(dtoFiltro.getId());
        } else {
            dtoFiltro.setId(null);
        }
        if (dtoFiltro.getDescripcion() != null && dtoFiltro.getDescripcion().length() != 0) {
            hqsql += " and upper(e.descripcion) like '%" + dtoFiltro.getDescripcion().toUpperCase() + "%' ";
        }
        hqsql += " and year(e.fechaFeriado) = '" + dtoFiltro.getAnio() + "'";

//        Calendar c = Calendar.getInstance();
//        c.set(2012, 1, 1);
//        c.set(Calendar.HOUR, 0);
//        c.set(Calendar.MINUTE, 0);
//        c.set(Calendar.SECOND, 0);
//        listaParametros.add(c.getTime());
//
//        c.set(2013, 12, 31);
//        c.set(Calendar.HOUR, 23);
//        c.set(Calendar.MINUTE, 59);
//        c.set(Calendar.SECOND, 59);
//        listaParametros.add(c.getTime());
        hqsql += " and e.ubigeoDto.id = ?";
        listaParametros.add(dtoFiltro.getUbigeoDto().getId());
        return springHibernateDao.ejecutarQuery(hqsql, listaParametros);

    }

    public String generarFechaInicioPorAnio(int anio) {
        return "01/01/"+anio;
    }
    
    public String generarFechaFinPorAnio(int anio) {
        return "31/12/"+anio;
    }

    /**
     * Metodo que genera en formato JSON los feriados por año y por pais
     *
     * @param dtoFiltro filtros
     * @return StringBuffer
     * @throws DAOException
     */
    public StringBuffer obtenerFeriadosPorPais(FeriadoPaisDto dtoFiltro) throws DAOException {
        StringBuffer sb = new StringBuffer();
        List<FeriadoPaisDto> lst = obtenerFeriadosPorPaisYAnio(dtoFiltro);
        if (!lst.isEmpty()) {
            sb.append("{");

            String comillasSimples = "'";
            String dosPuntos = ":";

            List<String> lstAnios = obtenerAnios(lst);

            for (int i = 0; i < lstAnios.size(); i++) {
                //Cargando los anios
                sb.append(comillasSimples);
                sb.append(lstAnios.get(i));
                sb.append(comillasSimples);
                sb.append(dosPuntos);
                sb.append("{"); //agrupar meses
                int year = Integer.parseInt(lstAnios.get(i));
                List<String> lstMesesAnio = obtenerMesesAnio(lst, year);

                for (int j = 0; j < lstMesesAnio.size(); j++) {
                    //Cargando los anios
                    sb.append(comillasSimples);
                    sb.append(lstMesesAnio.get(j));
                    sb.append(comillasSimples);
                    sb.append(dosPuntos);
                    int month = Integer.parseInt(lstMesesAnio.get(j));
                    sb.append("{"); //agrupar dias de cada mes
                    List<DiaFeriado> lstDiasMesesAnio = obtenerDiasMeseAnio(lst, month, year);
                    for (int k = 0; k < lstDiasMesesAnio.size(); k++) {
                        //Cargando los anios
                        sb.append(comillasSimples);
                        sb.append(lstDiasMesesAnio.get(k).getDia());
                        sb.append(comillasSimples);
                        sb.append(dosPuntos);
                        sb.append("'" + lstDiasMesesAnio.get(k).getDescripcion() + "'");
                        if (k + 1 < lstDiasMesesAnio.size()) {
                            sb.append(",");
                        }
                    }

                    sb.append("}");//cierre agrupar dias de cada mes
                    if (j + 1 < lstMesesAnio.size()) {
                        sb.append(",");
                    }
                }

                sb.append("}");//cierre agrupar meses
                if (i + 1 < lstAnios.size()) {
                    sb.append(",");
                }
            }
            sb.append("}");

        } else {
            sb.append("'N'");
        }
        return sb;
    }

    /**
     * Metodo para obtener los feriados por pais y fecha
     *
     * @param dtoFiltro filtros
     * @param fecha fecha del feriado
     * @return List<FeriadoPaisDto>
     * @throws DAOException
     */
    public List<FeriadoPaisDto> obtenerFeriadoPorFechaPais(FeriadoPaisDto dtoFiltro, String fecha) throws DAOException {
        List<Object> listaParametros = new ArrayList<Object>();
        String hqsql = "select e from FeriadoPaisDto as e where e.id=e.id";
        hqsql += " and e.ubigeoDto.id = ?";
        listaParametros.add(dtoFiltro.getUbigeoDto().getId());
        hqsql += " and e.fechaFeriado = '" + fecha + "'";
        return springHibernateDao.ejecutarQuery(hqsql, listaParametros);

    }

    /**
     * Metodo para obtener la cantidad de registros por pais y fecha
     *
     * @param dtoFiltro filtros
     * @param fecha fecha del feriado
     * @return int
     * @throws DAOException
     */
    public int obtenerCantidadFeriadoPorFechaPais(FeriadoPaisDto dtoFiltro, String fecha) throws DAOException {
        List<Object> listaParametros = new ArrayList<Object>();
        String hqsql = "select count(e.id) from FeriadoPaisDto as e ";
        hqsql += " where e.ubigeoDto.id = ? and e.fechaFeriado = '" + fecha + "'";
        listaParametros.add(dtoFiltro.getUbigeoDto().getId());
        return Integer.parseInt(springHibernateDao.ejecutarQueryGeneric(hqsql, listaParametros).get(0).toString());
    }

    /**
     * Metodo para obtener la lista de años por pais
     *
     * @param lst lista de Feriados
     * @return lista de String
     */
    private List<String> obtenerAnios(List<FeriadoPaisDto> lst) {
        List<String> anios = new ArrayList<String>();

        for (FeriadoPaisDto f : lst) {
            Calendar c = Calendar.getInstance();
            c.setTime(f.getFechaFeriado());
            int anio = c.get(Calendar.YEAR);
            if (!anios.contains(String.valueOf(anio))) {
                anios.add(String.valueOf(anio));
            }
        }
        return anios;
    }

    /**
     * Metodo para obtener la lista de meses por año y pais
     *
     * @param lst lista de Feriados
     * @param year año
     * @return lista de String
     */
    private List<String> obtenerMesesAnio(List<FeriadoPaisDto> lst, int year) {
        List<String> meses = new ArrayList<String>();

        for (FeriadoPaisDto f : lst) {
            Calendar c = Calendar.getInstance();
            c.setTime(f.getFechaFeriado());


            int anio = c.get(Calendar.YEAR);

            if (anio == year) {
                int mes = c.get(Calendar.MONTH) + 1;
                if (!meses.contains(String.valueOf(mes))) {
                    meses.add(String.valueOf(mes));
                }
            }
        }
        return meses;
    }

    /**
     * Metodo para obtener la lista de dias por mes/año
     *
     * @param lst lista de Feriados
     * @param month mes
     * @param year año
     * @return lista de String
     */
    private List<DiaFeriado> obtenerDiasMeseAnio(List<FeriadoPaisDto> lst, int month, int year) {
        List<DiaFeriado> dias = new ArrayList<DiaFeriado>();
        DiaFeriado diaFeriado = null;
        for (FeriadoPaisDto f : lst) {
            Calendar c = Calendar.getInstance();
            c.setTime(f.getFechaFeriado());


            int anio = c.get(Calendar.YEAR);
            int mes = c.get(Calendar.MONTH) + 1;
            if (anio == year && mes == month) {
                int dia = c.get(Calendar.DAY_OF_MONTH);
                if (!dias.contains(String.valueOf(dia))) {
                    diaFeriado = new DiaFeriado();
                    diaFeriado.setDia(String.valueOf(dia));
                    diaFeriado.setDescripcion(f.getDescripcion());
                    dias.add(diaFeriado);
                }
            }
        }
        return dias;
    }

    /**
     * Metodo para inicializar los atributos de un feriado
     *
     * @return Feriado
     */
    public FeriadoPaisDto inicializar() {
        FeriadoPaisDto dto = new FeriadoPaisDto();
        try {
            dto.setEstado(Boolean.TRUE);
            dto.setIndicadorFeriado('S');
            dto.setEstado(Boolean.TRUE);
        } catch (Exception ex) {
            recursosManager.showError(ex.getMessage());
            logger.error(ex.getMessage());
        }
        return dto;
    }

    /**
     * Metodo para guardar los datos de un feriado
     *
     * @param dto Feriado a guardar
     * @return Cadena de satisfaccion
     */
    public String guardar(FeriadoPaisDto dto) {

        String to = null;
        String mensajeTrx = "";
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");

        {
            dto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
            dto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
            dto.setTerminal(sessionMBean.getSessionTerminal());
        }

        if (sessionMBean.getAccion() == applicationMBean.getNuevo()) {
            try {
                dto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
                dto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                dto.setTerminalCreacion(sessionMBean.getSessionTerminal());
                UtilCore.General.toUpperCaseDto(dto);
                nuevo(dto);
                mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                recursosManager.showMessage(mensajeTrx);

                to = "";//retroceder();
            } catch (Exception ex) {
                mensajeTrx = ex.getMessage();
                recursosManager.showError(ex.getMessage());
                logger.error(mensajeTrx);

                to = null;
            }
        } else if (sessionMBean.getAccion() == applicationMBean.getEditar()) {
            try {
                UtilCore.General.toUpperCaseDto(dto);
                editar(dto);
                mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                recursosManager.showMessage(mensajeTrx);
                to = "";//retroceder();
            } catch (Exception ex) {
                mensajeTrx = ex.getMessage();
                recursosManager.showError(ex.getMessage());
                logger.error(mensajeTrx);
                to = null;
            }
        }



        return to;
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        FeriadoPaisManager.logger = logger;
    }

    public DAOGenerico<FeriadoPaisDto> getSpringHibernateDao() {
        return springHibernateDao;
    }

    public void setSpringHibernateDao(DAOGenerico<FeriadoPaisDto> springHibernateDao) {
        this.springHibernateDao = springHibernateDao;
    }

    public RecursosManager getRecursosManager() {
        return recursosManager;
    }

    public void setRecursosManager(RecursosManager recursosManager) {
        this.recursosManager = recursosManager;
    }

    public Long getIdEmpresaSystem() {
        return idEmpresaSystem;
    }

    public void setIdEmpresaSystem(Long idEmpresaSystem) {
        this.idEmpresaSystem = idEmpresaSystem;
    }

    public EmpresaDto getEmpresaSystem() {
        return empresaSystem;
    }

    public void setEmpresaSystem(EmpresaDto empresaSystem) {
        this.empresaSystem = empresaSystem;
    }

    public Long getIdEntidad() {
        return idEntidad;
    }

    public void setIdEntidad(Long idEntidad) {
        this.idEntidad = idEntidad;
    }

    public String getUrl() {
        return url;
    }

    public class DiaFeriado {

        private String dia;
        private String descripcion;

        public String getDia() {
            return dia;
        }

        public void setDia(String dia) {
            this.dia = dia;
        }

        public String getDescripcion() {
            return descripcion;
        }

        public void setDescripcion(String descripcion) {
            this.descripcion = descripcion;
        }
    }
}
